package com.yonyou.isv.demo.openapi.base.module.auth.tenant.impl;

import com.yonyou.isv.demo.openapi.base.module.token.OpenApiTokenCacheProvider;
import com.yonyou.isv.demo.openapi.base.properties.OpenApiProperties;
import com.yonyou.isv.demo.openapi.base.datacenter.DataCenterUrlProvider;
import com.yonyou.isv.demo.openapi.base.exception.BusinessException;
import com.yonyou.isv.demo.openapi.base.module.auth.pojo.OpenApiAccessTokenResponse;
import com.yonyou.isv.demo.openapi.base.module.auth.tenant.TenantAuthProvider;
import com.yonyou.isv.demo.openapi.base.module.common.OpenApiAccessToken;
import com.yonyou.isv.demo.openapi.base.network.OpenApiRequestEncryptor;
import com.yonyou.isv.demo.openapi.utils.RequestUtil;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;
import java.util.TreeMap;

/**
 * 本类主要用于
 *
 * @author liuhaoi
 * @since Created At 2020/5/11 11:00 上午
 */
@Slf4j
@RequiredArgsConstructor
public class TenantAuthProviderImpl implements TenantAuthProvider {

    private static final String URL_TOKEN = "open-auth/selfAppAuth/base/v1/getAccessToken?signature=%s&appKey=%s&timestamp=%s";

    private final OpenApiProperties properties;
    private final OpenApiRequestEncryptor encryptor;

    @Resource
    OpenApiTokenCacheProvider cacheProvider;

    @Resource
    DataCenterUrlProvider dataCenterUrlProvider;

    @SneakyThrows
    @Override
    public OpenApiAccessToken buildTenantAuthToken() {
        OpenApiAccessToken token = cacheProvider.loadTokenFromCache();
        if (token != null && token.getExpiredAt() > System.currentTimeMillis()) {
            return token;
        }
        return buildTenantAuthTokenFromRemote();

    }

    public OpenApiAccessToken buildTenantAuthTokenFromRemote() throws IOException {

        long timestamp = System.currentTimeMillis();
        String appKey = properties.getAppKey();
        Map<String, String> params = new TreeMap<>();
        params.put("appKey", appKey);
        params.put("timestamp", String.valueOf(timestamp));
        String signature = encryptor.signature(params, properties.getAppSecret());

        String url = properties.concatURL(dataCenterUrlProvider.buildTokenUrl(), String.format(URL_TOKEN, signature, appKey, timestamp));

        OpenApiAccessTokenResponse body = RequestUtil.doGet(url,null,OpenApiAccessTokenResponse.class);

        if (body != null) {
            body.check();
            OpenApiAccessToken accessToken = body.getData().build();
            cacheProvider.saveTokenToCache(accessToken);
            return accessToken;
        }

        throw new BusinessException("Unexpected empty response encountered when request open api access token");
    }

}
